﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace L08
{
    class Program
    {
        static void Main(string[] args)
        {
            LinkList<string> link = new LinkList<string>();
            link.first = new LineNode<string>("1");
            link.first.data = "1";
            link.InsertAt("2", 1);
            link.InsertAt("2", 2);
            link.InsertAt("3", 2);
            link.InsertAt("4", 2);
            link.InsertAt("5", 2);
            link.InsertAt("6", 2);
            link.IndexOf(link.First);
            link.RemoveAt(1);
            Console.ReadKey();
        }

        private class T
        {
        }
    }
    class LineNode<T>
    {
        T Data;
        public LineNode<T> Next;

        public T data { get; internal set; }


        public LineNode(T a)
        {
            this.Data = a;
        }

        public LineNode()
        {
        }
    }
    interface ILinkable<T>
    {
        void LineNode(T a);
    }
    class LinkList<T>
    {
        public LineNode<T> first;
        private readonly int count = 0;


        public LineNode<T> First
        {
            get { return first; }
            set { first = value; }
        }
        public LinkList()
        {
            first = null;
        }
        public bool IsEmpty()
        {

            return first == null;


        }
        public int Count
        {
            get
            {
                int i = 0;
                LineNode<T> node = first;
                while (node.Next != null)
                {
                    i++;
                }
                return i;
            }
        }
        public LineNode<T> GetNode(int pos)
        {
            LineNode<T> node = first;
            for (int i = 0; i < pos; i++)
            {
                if (node.Next == null)
                {
                    throw new IndexOutOfRangeException();
                }
                node = node.Next;
            }
            return node;
        }

        public T this[int i]
        {
            get
            {
                return this.GetNode(i).data;
            }
        }


        public int IndexOf(LineNode<T> value)
        {
            LineNode<T> node = first;
            for (int i = 0; i < count; i++)
            {

                if (node.Next == value)
                {
                    return i;
                }
            }
            return -1;
        }

        public void InsertAt(T value, int index)
        {
            if (first == null || index < 1 || index > Count)
            {
                Console.WriteLine("链表为空，或插入位置小于0,或输入的数字大于链表长度");
                return;
            }
            if (index == 1)

            {

                LineNode<T> c = new LineNode<T>();
                c.data = value;
                c.Next = first;
                first = c;
                return;
            }
            LineNode<T> p = first;//这个结点是保存当，链表被分隔开后的前半部分
            LineNode<T> q = new LineNode<T>();
            int j = 1;
            while (p.Next != null && j < index)
            {
                //假如输入的2，那么只打印了1个结点，第二个结点暂时为空
                q = p;
                p = p.Next;//Console.WriteLine("输入2："+ p.data);
                ++j;
            }
            if (j == index)
            {
                //a结点就是将要插入第二个位置的结点
                LineNode<T> a = new LineNode<T>();

                a.data = value;//a结点的下一个结点，相当于就是插入分隔后的第一个结点作为头，链接剩余的子节点,即链表的后半部分
                a.Next = p;//最后再将上半部分最后一个结点的下一个结点（原本是为空），将a赋值给它；
                q.Next = a;
            }
        }

        public T RemoveAt(int i)
        {
            if (i < 0)
            {
                Console.WriteLine("Link is empty or Position is error!");
                return default(T);
            }
            LineNode<T> q = new LineNode<T>();
            if (i == 0)
            {
                q = first;
                first = first.Next;
                return q.data;
            }
            LineNode<T> p = first;
            int j = 0;
            while (p.Next != null && j < i)
            {
                j++;
                q = p;
                p = p.Next;
            }
            if (j == i)
            {
                q.Next = p.Next;
                return p.data;
            }
            else
            {
                Console.WriteLine("节点不存在!");
                return default(T);
            }
        }


    }
}
